<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
<script>

let plugin = (function() {
  let plugin = document.createElement('embed');
  plugin.style.display = 'none';

  plugin.type = 'application/txftn-webkit';
  plugin.sign = function() {
    console.log('开始文件扫描');
  }
  plugin.pause = function() {
    console.log('暂停文件上传');
  }
  plugin.uploading = function() {
    console.log('开始文件上传');
  }
  plugin.del = function() {
    console.log('删除文件上传');
  }
  plugin.done = function() {
    console.log('文件上传完成');
  }
  document.body.appendChild(plugin);
  return plugin;
})()

class Upload {
  constructor(fileName) {
    this.plugin = plugin;
    this.fileName = fileName;
    this.button1 = null;
    this.button2 = null;
    this.state = 'sign'; // 设置初始状态为 waiting
  }
  init() {
    // 创建节点：用于控制上传流程的按钮
    this.dom = document.createElement('div');
    this.dom.innerHTML = `
      <span>文件名称：${this.fileName}</span>
      <button data-action="button1">扫描中</button>
      <button data-action="button2">删除</button>
    `
    document.body.appendChild(this.dom)
    this.button1 = this.dom.querySelector('[data-action="button1"]')
    this.button2 = this.dom.querySelector('[data-action="button2"]')
    // 绑定点击事件
    this.bindEvent()
  }
  bindEvent() {
    this.button1.onclick = () => {
      switch(this.state) {
        case 'sign': // 扫描状态下，任何操作无效
          console.log('扫描中，点击无效...');
          break;
        case 'uploading': // 上传中，点击切换到暂停
          this.changeState('pause');
          break;
        case 'pause': // 暂停中，点击切换到上传中
          this.changeState('uploading');
          break;
        case 'done':
          console.log('文件已完成上传, 点击无效'); 
          break;
        case 'error':
          console.log('文件上传失败, 点击无效');
          break;
      }
    }
    this.button2.onclick = () => {
      switch(this.state) {
        case 'done':
        case 'error':
        case 'pause':
          // 上传完成、上传失败和暂停状态下可以删除
          this.changeState('del');
          break;
        case 'sign':
          console.log('文件正在扫描中，不能删除'); 
          break;
        case 'uploading':
          console.log('文件正在上传中，不能删除');
          break;
      }
    }
  }
  // 切换状态后的具体行为 -- 改变按钮的innerHTML+调用插件开始‘真正’的操作
  changeState(state) {
    switch(state) {
      case 'sign':
        this.plugin.sign();
        this.button1.innerHTML = '扫描中，任何操作无效';
        break;
      case 'uploading':
        this.plugin.uploading();
        this.button1.innerHTML = '正在上传，点击暂停';
        break;
      case 'pause':
        this.plugin.pause();
        this.button1.innerHTML = '已暂停，点击继续上传';
        break;
      case 'done':
        this.plugin.done();
        this.button1.innerHTML = '上传完成';
        break;
      case 'error':
        this.button1.innerHTML = '上传失败';
        break;
      case 'del':
        this.plugin.del();
        this.dom.parentNode.removeChild(this.dom);
        console.log('删除完成');
        break;
    }
    this.state = state;
  }
}
let uploadObj = new Upload('js设计模式及开发实践')
uploadObj.init()
window.external.upload = function(state) {
  uploadObj.changeState(state);
}
window.external.upload('sign') // 文件开始扫描
setTimeout(() => {
  window.external.upload('uploading'); // 1 秒后开始上传
}, 1000);
setTimeout(() => {
  window.external.upload('done'); // 5 秒后上传完成
}, 5000);
</script>
</body>
</html>